/*
 * @Author: 13177709051 3506463075@qq.com
 * @Date: 2024-12-04 11:13:31
 * @LastEditors: 13177709051 3506463075@qq.com
 * @LastEditTime: 2024-12-04 18:10:40
 * @FilePath: /highly-concurrent-server/test/tcp_server.cc
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
#include "../source/server.hpp"

void HandleClose(Channel *channel)
{
    DBG_LOG("close fd : %d", channel->Fd());
    channel->Remove(); // 移除监控
    delete channel;
}

void HandleRead(Channel *channel)
{
    int fd = channel->Fd();
    char buf[1024] = {0};
    int ret = recv(fd, buf, 1023, 0);
    if(ret <= 0)
    {
        return HandleClose(channel); // 关闭释放
    }
    DBG_LOG("%s", buf);
    channel->EnableWrite(); // 启动可写事件
}

void HandlWrite(Channel *channel)
{
    int fd = channel->Fd();
    const char *data = "天气还不错!!";
    int ret = send(fd, data, strlen(data), 0);
    if(ret < 0)
    {
        return HandleClose(channel); // 关闭释放
    }
}

void HandleError(Channel *channel)
{
    return HandleClose(channel); // 关闭释放
}

void HandleEvent(EventLoop *loop, Channel *channel, uint64_t timerid)
{
    loop->TimerRefresh(timerid);
}

void Acceptor(EventLoop *loop, Channel *lst_channel)
{
    int fd = lst_channel->Fd();
    int newfd = accept(fd, NULL, NULL);
    if(newfd < 0) {return;}

    uint64_t timerid = rand() % 10000;
    Channel *channel = new Channel(loop, newfd);
    channel->SetReadCallback(std::bind(HandleRead, channel));
    channel->SetWriteCallback(std::bind(HandlWrite, channel));
    channel->SetCloseCallback(std::bind(HandleClose, channel));
    channel->SetErrorCallback(std::bind(HandleError, channel));
    channel->SetEventCallback(std::bind(HandleEvent, loop, channel, timerid));
    loop->TimerAdd(timerid, 10, std::bind(HandleClose, channel));
    channel->EnableRead();
}

int main()
{
    EventLoop loop;
    Socket lst_sock;
    lst_sock.CreateServer(8080);
    // 为监听套接字, 创建一个 Channel 进行事件管理, 以及事件的处理
    Channel channel(&loop, lst_sock.Fd());
    // 回调中, 获取新连接, 为新连接创建 Channel 并且添加监控
    channel.SetReadCallback(std::bind(Acceptor, &loop, &channel));
    channel.EnableRead();// 启动可读事件监控
    while(1)
    {
        loop.Start();
    }
    lst_sock.Close();
    return 0;
}